﻿// Project: Salient
// http://salient.codeplex.com
// 
// Copyright 2010, Sky Sanders <sky at skysanders.net>
// Dual licensed under the MIT or GPL Version 2 licenses.
// http://salient.codeplex.com/license
// 
// Date: April 16 2010 

#region

using System;
using System.IO;
using Microsoft.Win32;

#endregion

namespace Salient.Web
{
    ///<summary>
    ///</summary>
    public class UploadFile : IDisposable
    {
        private readonly bool _ownStream;


        ///<summary>
        ///</summary>
        /// <param name="data">An open, positioned stream containing the file data</param>
        /// <param name="fileName">A name to assign to the file data and from which to infer <code>fileContentType</code> if necessary</param>
        public UploadFile(Stream data, string fileName)
            : this(data, fileName, default(string), default(string))
        {
        }

        ///<summary>
        ///</summary>
        /// <param name="data">An open, positioned stream containing the file data</param>
        /// <param name="fileName">A name to assign to the file data and from which to infer <code>fileContentType</code> if necessary</param>
        /// <param name="contentType">Optional. If omitted, registry is queried using <paramref name="fileName"/>. 
        /// If content type is not available from registry, application/octet-stream will be submitted.</param>
        /// <param name="fieldName">Optional, a form field name to assign to the uploaded file data. 
        /// If ommited the value 'file' will be submitted.</param>
        public UploadFile(Stream data, string fileName, string contentType, string fieldName)
            
        {

            if (data == null)
            {
                throw new ArgumentNullException("data");
            }
            if (string.IsNullOrEmpty(fileName))
            {
                throw new ArgumentNullException("fileName");
            }
            Data = data;
            FileName = fileName;

            ContentType = contentType;
            FieldName = fieldName;

            FieldName = string.IsNullOrEmpty(fieldName) ?
                String.Format("file{0:N}", Guid.NewGuid()) : 
                FieldName;

            if (string.IsNullOrEmpty(contentType))
            {
                string cType;
                ContentType = ContentTypes.TryGetContentType(fileName, out cType) ? cType : "application/octet-stream";
            }
        }

        ///<summary>
        ///</summary>
        /// <param name="fileName">The physical path of the file to upload</param>
        public UploadFile(string fileName)
            : this(fileName, default(string), default(string))
        {
        }

        ///<summary>
        ///</summary>
        /// <param name="fileName">The physical path of the file to upload</param>
        /// <param name="contentType">Optional. If omitted, registry is queried using <paramref name="fileName"/>. 
        /// If content type is not available from registry, application/octet-stream will be submitted.</param>
        /// <param name="fieldName">Optional, a form field name to assign to the uploaded file data. 
        /// If ommited the value 'file' will be submitted.</param>
        public UploadFile(string fileName, string contentType, string fieldName):this(new MemoryStream(),fileName,contentType,fieldName)
        {
            Data = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            _ownStream = true;
        }

        ///<summary>
        ///</summary>
        public string ContentType { get; internal set; }

        ///<summary>
        ///</summary>
        public Stream Data { get; private set; }

        ///<summary>
        ///</summary>
        public string FieldName { get; private set; }

        ///<summary>
        ///</summary>
        public string FileName { get; private set; }

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            if (Data != null && _ownStream)
            {
                Data.Close();
                Data.Dispose();
                Data = null;
            }
        }


    }
}